#include "obj_string.h"
#include <string.h>
#include "vm.h"
#include "utils.h"
#include "common.h"
#include <stdlib.h>

// fnv-la算法，用来计算hash值
// str字符串起点地址，length长度
uint32_t hashString(char *str, uint32_t length) {
    uint32_t hashCode = 2166136261, idx = 0;
    while (idx < length) {
        hashCode ^= str[idx];
        hashCode *= 16777619;
        idx++;
    }
    return hashCode;
}

void hashObjString(ObjString *objString) {
    objString->hashCode =
            hashString(objString->value.start, objString->value.length);
}

// 为用户创建字符串对象
ObjString *newObjString(VM *vm, const char *str, uint32_t length) {

    //length为0时str必为NULL length不为0时str不为NULL
    ASSERT(length == 0 || str != NULL, "str length don`t match str!");

    // 为对象分配内存   length+1是为了在后面加上\0
    ObjString *objString = ALLOCATE_EXTRA(vm, ObjString, length + 1);

    // 为对象分配内存失败
    if (objString == NULL) {
        MEM_ERROR("Allocating ObjString failed!");
    }
    initObjHeader(vm, &objString->objHeader, OT_STRING, vm->stringClass);
    objString->value.length = length;

    // 支持空字符串 str==null&&length ==0
    // 如果非空则复制内容
    if (length > 0) {
        memcpy(objString->value.start, str, length);
    }

    // 字符串结尾加上结束符
    objString->value.start[length] = '\0';
    hashObjString(objString);
    return objString;
}
